# -*- mode: Perl -*-
# /=====================================================================\ #
# |  IEEEtran.cls                                                       | #
# | Implementation for LaTeXML                                          | #
# |=====================================================================| #
# | Part of LaTeXML:                                                    | #
# |  Public domain software, produced as part of work done by the       | #
# |  United States Government & not subject to copyright in the US.     | #
# |---------------------------------------------------------------------| #
# | Bruce Miller <bruce.miller@nist.gov>                        #_#     | #
# | http://dlmf.nist.gov/LaTeXML/                              (o o)    | #
# \=========================================================ooo==U==ooo=/ #
package LaTeXML::Package::Pool;
use strict;
use warnings;
use LaTeXML::Package;

RawTeX(<<'EoTeX');
\newif\ifCLASSOPTIONonecolumn       \CLASSOPTIONonecolumnfalse
\newif\ifCLASSOPTIONtwocolumn       \CLASSOPTIONtwocolumntrue
\newif\ifCLASSOPTIONoneside         \CLASSOPTIONonesidetrue
\newif\ifCLASSOPTIONtwoside         \CLASSOPTIONtwosidefalse
\newif\ifCLASSOPTIONfinal           \CLASSOPTIONfinaltrue
\newif\ifCLASSOPTIONdraft           \CLASSOPTIONdraftfalse
\newif\ifCLASSOPTIONdraftcls        \CLASSOPTIONdraftclsfalse
\newif\ifCLASSOPTIONdraftclsnofoot  \CLASSOPTIONdraftclsnofootfalse
\newif\ifCLASSOPTIONpeerreview      \CLASSOPTIONpeerreviewfalse
\newif\ifCLASSOPTIONpeerreviewca    \CLASSOPTIONpeerreviewcafalse
\newif\ifCLASSOPTIONjournal         \CLASSOPTIONjournaltrue
\newif\ifCLASSOPTIONconference      \CLASSOPTIONconferencefalse
\newif\ifCLASSOPTIONtechnote        \CLASSOPTIONtechnotefalse
\newif\ifCLASSOPTIONnofonttune      \CLASSOPTIONnofonttunefalse
\newif\ifCLASSOPTIONcaptionsoff     \CLASSOPTIONcaptionsofffalse
\newif\ifCLASSOPTIONcomsoc          \CLASSOPTIONcomsocfalse
\newif\ifCLASSOPTIONcompsoc         \CLASSOPTIONcompsocfalse
\newif\ifCLASSOPTIONtransmag        \CLASSOPTIONtransmagfalse
\newif\ifCLASSOPTIONromanappendices \CLASSOPTIONromanappendicesfalse
\newif\ifCLASSINFOpdf               \CLASSINFOpdffalse
% Probably need to pretend pdf?
\CLASSINFOpdftrue
%
\DeclareOption{9pt}{\def\CLASSOPTIONpt{9}\def\@ptsize{0}}
\DeclareOption{10pt}{\def\CLASSOPTIONpt{10}\def\@ptsize{0}}
\DeclareOption{11pt}{\def\CLASSOPTIONpt{11}\def\@ptsize{1}}
\DeclareOption{12pt}{\def\CLASSOPTIONpt{12}\def\@ptsize{2}}
\DeclareOption{letterpaper}{\setlength{\paperwidth}{8.5in}%
                            \setlength{\paperheight}{11in}%
%%                            \@IEEEusingAfourpaperfalse
%%                            \@IEEEusingcspaperfalse
                            \def\CLASSOPTIONpaper{letter}%
                            \def\CLASSINFOpaperwidth{8.5in}%
                            \def\CLASSINFOpaperheight{11in}}
\DeclareOption{a4paper}{\setlength{\paperwidth}{210mm}%
                        \setlength{\paperheight}{297mm}%
%%                        \@IEEEusingAfourpapertrue
%%                        \@IEEEusingcspaperfalse
                        \def\CLASSOPTIONpaper{a4}%
                        \def\CLASSINFOpaperwidth{210mm}%
                        \def\CLASSINFOpaperheight{297mm}}
% special paper option for compsoc journals
\DeclareOption{cspaper}{\setlength{\paperwidth}{7.875in}%
                        \setlength{\paperheight}{10.75in}%
%%                        \@IEEEusingcspapertrue
%%                        \@IEEEusingAfourpaperfalse
                        \def\CLASSOPTIONpaper{ieeecs}%
                        \def\CLASSINFOpaperwidth{7.875in}%
                        \def\CLASSINFOpaperheight{10.75in}}
\DeclareOption{oneside}{\@twosidefalse\@mparswitchfalse
                        \CLASSOPTIONonesidetrue\CLASSOPTIONtwosidefalse}
\DeclareOption{twoside}{\@twosidetrue\@mparswitchtrue
                        \CLASSOPTIONtwosidetrue\CLASSOPTIONonesidefalse}
\DeclareOption{onecolumn}{\CLASSOPTIONonecolumntrue\CLASSOPTIONtwocolumnfalse}
\DeclareOption{twocolumn}{\CLASSOPTIONtwocolumntrue\CLASSOPTIONonecolumnfalse}
\DeclareOption{draft}{\CLASSOPTIONdrafttrue\CLASSOPTIONdraftclstrue
                      \CLASSOPTIONdraftclsnofootfalse}
% draftcls is for a draft mode which will not affect any packages
% used by the document.
\DeclareOption{draftcls}{\CLASSOPTIONdraftfalse\CLASSOPTIONdraftclstrue
                         \CLASSOPTIONdraftclsnofootfalse}
% draftclsnofoot is like draftcls, but without the footer.
\DeclareOption{draftclsnofoot}{\CLASSOPTIONdraftfalse\CLASSOPTIONdraftclstrue
                               \CLASSOPTIONdraftclsnofoottrue}
\DeclareOption{final}{\CLASSOPTIONdraftfalse\CLASSOPTIONdraftclsfalse
                      \CLASSOPTIONdraftclsnofootfalse}

\DeclareOption{journal}{\CLASSOPTIONpeerreviewfalse\CLASSOPTIONpeerreviewcafalse
                        \CLASSOPTIONjournaltrue\CLASSOPTIONconferencefalse\CLASSOPTIONtechnotefalse}

\DeclareOption{conference}{\CLASSOPTIONpeerreviewfalse\CLASSOPTIONpeerreviewcafalse
                           \CLASSOPTIONjournalfalse\CLASSOPTIONconferencetrue\CLASSOPTIONtechnotefalse}

\DeclareOption{technote}{\CLASSOPTIONpeerreviewfalse\CLASSOPTIONpeerreviewcafalse
                         \CLASSOPTIONjournalfalse\CLASSOPTIONconferencefalse\CLASSOPTIONtechnotetrue}

\DeclareOption{peerreview}{\CLASSOPTIONpeerreviewtrue\CLASSOPTIONpeerreviewcafalse
                           \CLASSOPTIONjournalfalse\CLASSOPTIONconferencefalse\CLASSOPTIONtechnotefalse}

\DeclareOption{peerreviewca}{\CLASSOPTIONpeerreviewtrue\CLASSOPTIONpeerreviewcatrue
                             \CLASSOPTIONjournalfalse\CLASSOPTIONconferencefalse\CLASSOPTIONtechnotefalse}

\DeclareOption{nofonttune}{\CLASSOPTIONnofonttunetrue}
\DeclareOption{captionsoff}{\CLASSOPTIONcaptionsofftrue}
\DeclareOption{comsoc}{\CLASSOPTIONcomsoctrue\CLASSOPTIONcompsocfalse\CLASSOPTIONtransmagfalse\RequirePackage{newtxmath}}
\DeclareOption{compsoc}{\CLASSOPTIONcomsocfalse\CLASSOPTIONcompsoctrue\CLASSOPTIONtransmagfalse}
\DeclareOption{transmag}{\CLASSOPTIONtransmagtrue\CLASSOPTIONcomsocfalse\CLASSOPTIONcompsocfalse}
\DeclareOption{romanappendices}{\CLASSOPTIONromanappendicestrue}

EoTeX

# #  9pt 10pt 11pt 12pt
# foreach my $option (qw(
#   draft draftcls draftclsnofoot final
#   conference journal technote peerreview peerreviewca
#   comsoc compsoc transmag
#   letterpaper a4paper cspaper
#   oneside twoside
#   oncolumn twocolumn
#   romanappendices
#   captionsoff
#   nofonttune)) {
#   DeclareOption($option, undef); }

# Anything else gets passed to article.
DeclareOption(undef, sub {
    PassOptions('article', 'cls', ToString(Expand(T_CS('\CurrentOption')))); });

ProcessOptions();
LoadClass('article');

#RequirePackage('multicol');
#RequirePackage('inst_support');

# This seems to be just to save stuff so that \maketitle can format it?
DefMacro('\IEEEtitleabstractindextext{}',                '#1');
DefMacro('\IEEEdisplaynontitleabstractindextext',        '');
DefMacro('\IEEEdisplaynotcompsoctitleabstractindextext', '');
DefMacro('\IEEEcompsoctitleabstractindextext',           '');
Let('\IEEEpeerreviewmaketitle', '\maketitle');
DefMacro('\IEEEoverridecommandlockouts', '');
# V1.7 and later no longer supports \overrideIEEEmargins
DefMacro('\overrideIEEEmargins', '');

DefMacro('\IEEEaftertitletext{}',     '');    # ?
DefMacro('\IEEEspecialpapernotice{}', '');    # ?

DefMacro('\IEEEmembership{}',   '');          # nothing for now.
DefMacro('\IEEEauthorblockN{}', '#1');        # author

DefConstructor('\@@@affiliation{}', "^ <ltx:contact role='affiliation'>#1</ltx:contact>");
DefMacro('\IEEEauthorblockA{}', '\@add@to@frontmatter{ltx:creator}{\@@@affiliation{#1}}');

DefMacro(T_CS('\begin{IEEEkeywords}'), '\@IEEEkeywords');
DefMacro(T_CS('\end{IEEEkeywords}'),   '\@endIEEEkeywords');
Let('\@endIEEEkeywords', '\relax');                # stub
DefMacro('\@IEEEkeywords XUntil:\@endIEEEkeywords', '\@add@frontmatter{ltx:keywords}[name={\IEEEkeywordsname}]{#1}');
DefMacro('\IEEEraisesectionheading{}', '#1');
DefMacro('\IEEEPARstart{}{}',          '#1#2');    # Eventually, dropcap?

DefMacro('\IEEEcompsocitemizethanks{}', '\thanks{#1}');
DefMacro('\IEEEcompsocthanksitem[]',    '');
DefMacro('\IEEEauthorrefmark',          '');
DefMacro('\IEEEtriggeratref{}',         '');

DefMacro('\IEEEpubid{}',     '\@add@frontmatter{ltx:note}[role=publicationid]{pubid: #1}');
DefMacro('\IEEEpubidadjcol', '');

RawTeX(<<'EoTeX');
\ifCLASSOPTIONcompsoc
% compsoc is all arabic
\def\thesection{\arabic{section}}
\def\thesubsection{\thesection.\arabic{subsection}}
\def\thesubsubsection{\thesubsection.\arabic{subsubsection}}
\def\theparagraph{\thesubsubsection.\arabic{paragraph}}
\else
\def\thesection{\Roman{section}}                             % I
% V1.7, \mbox prevents breaks around -
\def\thesubsection{\mbox{\thesection-\Alph{subsection}}}     % I-A
% V1.7 use I-A1 format used by the IEEE rather than I-A.1
\def\thesubsubsection{\thesubsection\arabic{subsubsection}}  % I-A1
\def\theparagraph{\thesubsubsection\alph{paragraph}}         % I-A1a
\fi
EoTeX
DefMacro('\format@title@font@section',    '\sc');
DefMacro('\format@title@font@subsection', '\it');
DefMacro('\figurename',                   'Fig.');
DefMacro('\tablename',                    'TABLE');
DefMacro('\thetable',                     '\Roman{table}');

DefConstructor('\IEEEQEDclosed',
  "?#isMath(<ltx:XMTok role='PUNCT'>\x{220E}</ltx:XMTok>)(\x{220E})");
Let('\IEEEQEDopen', '\IEEEQEDclosed');
Let('\IEEEQED',     '\IEEEQEDclosed');

DefMacro('\IEEEQEDhere', sub {
    my $t = PopValue('QED@stack');
    PushValue('QED@stack', Tokens());
    $t || (); });

# Apparently no title...
DefEnvironment('{IEEEproof} OptionalUndigested',
  "<ltx:proof class='#class'>"
    . "<ltx:title font='#titlefont' _force_font='true' class='#titleclass'>#title</ltx:title>"
    . "#body",
  #  beforeDigest => sub {
  #    Digest(T_CS('\th@proof')); },
  afterConstruct   => sub { $_[0]->maybeCloseElement('ltx:proof'); },
  afterDigestBegin => sub {
    my ($stomach, $whatsit) = @_;
    PushValue('QED@stack', T_CS('\qed'));
    #    Digest(Tokens(T_CS('\the'), T_CS('\thm@bodyfont')));
  },
  properties => sub {
    my $title     = Digest(TokenizeInternal('\textbf{\textit{Proof:}}'));
    my $titlefont = [$title->unlist]->[1];
    $titlefont = $titlefont->getFont if $titlefont;
    (title => $title,
      titlefont  => $titlefont,
      class      => undef,
      titleclass => 'ltx_runin'); },
  beforeDigestEnd => sub {
    my $qed = PopValue('QED@stack');
    ($qed ? Digest($qed) : ()); }
);

RawTeX(<<'EoTeX');
\newlength\abovecaptionskip
\newlength\belowcaptionskip
\setlength\abovecaptionskip{0.5\baselineskip}
\setlength\belowcaptionskip{0pt}
EoTeX

DefEnvironment('{IEEEbiography}[]{}',
  "<ltx:float class='biography'><ltx:tabular>"
    . "<ltx:tr><ltx:td>#1</ltx:td><ltx:td><ltx:inline-block><ltx:text class='ltx_font_bold'>#2</ltx:text> "
    . "#body</ltx:inline-block></ltx:td></ltx:tr>"
    . "</ltx:tabular></ltx:float>");
DefEnvironment('{IEEEbiographynophoto}[]{}',
  "<ltx:float class='biography'><ltx:tabular>"
    . "<ltx:tr><ltx:td><ltx:inline-block><ltx:text class='ltx_font_bold'>#2</ltx:text> "
    . "#body</ltx:inline-block></ltx:td></ltx:tr>"
    . "</ltx:tabular></ltx:float>");

# IEEEeqnarray is similar to eqnarray, but supports subequation numbering.
# These turn on/off (sub)numbering, much like \nonumber  TODO Sort this out!
# Starred forms?
DefPrimitive('\IEEEnonumber OptionalMatch:*', sub {
    my $numbering = LookupValue('EQUATION_NUMBERING');
    my $tags      = LookupValue('EQUATIONROW_TAGS');
    if ($_[1]) {
      $$numbering{retract} = 1;
      $$numbering{counter} = undef; }
    else {
      $$tags{retract} = 1;
      $$tags{counter} = undef; }
    return; });

DefPrimitive('\IEEEyesnumber OptionalMatch:*', sub {
    my $numbering = LookupValue('EQUATION_NUMBERING');
    my $tags      = LookupValue('EQUATIONROW_TAGS');
    if (($$numbering{counter} || 'equation') eq 'subequation') {    # Reset any subnumbering
      RefStepCounter('equation'); }
    if ($_[1]) {
      $$numbering{retract} = 0;
      $$numbering{counter} = undef; }
    else {
      $$tags{noretract} = 1;
      $$tags{counter}   = undef; }
    return; });

DefPrimitive('\IEEEyessubnumber OptionalMatch:*', sub {
    my $numbering = LookupValue('EQUATION_NUMBERING');
    my $tags      = LookupValue('EQUATIONROW_TAGS');
    if ($_[1]) {
      $$numbering{counter} = 'subequation'; }
    else {
      $$tags{counter} = 'subequation'; }
    if ($$tags{preset} || $$numbering{preset}) {
      RefStepCounter('subequation'); }
    return; });

DefPrimitive('\IEEEnosubnumber OptionalMatch:*', sub {
    my $numbering = LookupValue('EQUATION_NUMBERING');
    my $tags      = LookupValue('EQUATIONROW_TAGS');
    if ($_[1]) {
      $$numbering{counter} = 'equation'; }
    else {
      $$tags{counter} = 'equation'; }
    return; });

# TODO: The argument is a column specification, like rCl
# We really should parse that and set up the column spec apppropriately,
# but it's different from the standard set of specs!
DefMacroI(T_CS('\IEEEeqnarray'), '{}', '\eqnarray');
Let(T_CS('\endIEEEeqnarray'), T_CS('\endeqnarray'));
DefMacroI(T_CS('\IEEEeqnarray*'), '{}', T_CS('\eqnarray*'));
Let(T_CS('\endIEEEeqnarray*'), T_CS('\endeqnarray*'));

# Let's try to treat \IEEEeqnarraybox as a variant of \array
# Note that the documentation suggests that IEEEeqnarraybox can be used INSIDE math for
# things like cases statements! Argh!!!

DefColumnType('L', sub {
    $LaTeXML::BUILD_TEMPLATE->addColumn(after => Tokens(T_CS('\hfil'))); return; });
DefColumnType('C', sub {
    $LaTeXML::BUILD_TEMPLATE->addColumn(before => Tokens(T_CS('\hfil')),
      after => Tokens(T_CS('\hfil'))); return; });
DefColumnType('R', sub {
    $LaTeXML::BUILD_TEMPLATE->addColumn(before => Tokens(T_CS('\hfil'))); return; });

DefMacro('\IEEEeqnarraybox',
  '\ifmmode\def\@tempa{\let\endIEEEeqnarraybox\endIEEEeqnarrayboxm\IEEEeqnarrayboxm}'
    . '\else\def\@tempa{\let\endIEEEeqnarraybox\endIEEEeqnarrayboxt\IEEEeqnarrayboxt}\fi'
    . '\@tempa');
DefMacro('\IEEEeqnarrayboxm OptionalMatch:* {}',
  '\@array@bindings{#2}\@@IEEE@array{#2}\@start@alignment');
DefMacroI('\endIEEEeqnarrayboxm', undef,
  '\@finish@alignment\@end@array');
DefMacro('\IEEEeqnarrayboxt OptionalMatch:* {}',
  '\@@BEGININLINEMATH\@array@bindings{#2}\@@IEEE@array{#2}\@start@alignment');
DefMacroI('\endIEEEeqnarrayboxt', undef,
  '\@finish@alignment\@end@array\@@ENDINLINEMATH');

DefConstructor('\@@IEEE@array[] Undigested DigestedBody',
  '#3',
  beforeDigest => sub { $_[0]->bgroup; },
  reversion    => '\begin{IEEEeqnarraybox}[#1]{#2}#3\end{IEEEeqnarraybox}');

DefMacro('\IEEEeqnarraynumspace', '');

Let(T_CS('\appendices'), T_CS('\appendix'));

$$LaTeXML::Package::Pool::BIBSTYLES{IEEEtran} = { citestyle => 'numbers', sort => 'true' };

DefMacro('\IEEEsetlabelwidth{}',  '\settowidth{\labelwidth}{#1}');
DefMacro('\IEEEusemathlabelsep',  '');
DefMacro('\IEEEtriggercmd{}',     '');
DefMacro('\IEEElabelindent',      '');
DefMacro('\IEEEcalcleftmargin{}', '');
DefMacro('\IEEEiedlabeljustifyc', '');
DefMacro('\IEEEiedlabeljustifyl', '');
DefMacro('\IEEEiedlabeljustifyr', '');

DefEnvironment('{IEEEitemize}',
  "<ltx:itemize xml:id='#id'>#body</ltx:itemize>",
  properties      => sub { beginItemize('itemize', '@item'); },
  beforeDigestEnd => sub { Digest('\par'); },
  locked          => 1, mode => 'text');
DefEnvironment('{IEEEenumerate}',
  "<ltx:enumerate  xml:id='#id'>#body</ltx:enumerate>",
  properties      => sub { beginItemize('enumerate', 'enum'); },
  beforeDigestEnd => sub { Digest('\par'); },
  locked          => 1, mode => 'text');
DefEnvironment('{IEEEdescription}',
  "<ltx:description  xml:id='#id'>#body</ltx:description>",
  beforeDigest    => sub { Let('\makelabel', '\descriptionlabel'); },
  properties      => sub { beginItemize('description', '@desc'); },
  beforeDigestEnd => sub { Digest('\par'); },
  locked          => 1, mode => 'text');

# V1.7 provide string macros as article.cls does
DefMacro('\contentsname',     'Contents');
DefMacro('\listfigurename',   'List of Figures');
DefMacro('\listtablename',    'List of Tables');
DefMacro('\refname',          'References');
DefMacro('\indexname',        'Index');
DefMacro('\figurename',       'Fig.');
DefMacro('\tablename',        'TABLE');
DefMacro('\figurename',       'Figure');
DefMacro('\partname',         'Part');
DefMacro('\appendixname',     'Appendix');
DefMacro('\abstractname',     'Abstract');
DefMacro('\IEEEkeywordsname', 'Index Terms');
DefMacro('\IEEEproofname',    'Proof');

# V1.8a no more support for these legacy commands
Let('\authorblockA',       '\IEEEauthorblockA');
Let('\authorblockN',       '\IEEEauthorblockN');
Let('\authorrefmark',      '\IEEEauthorrefmark');
Let('\PARstart',           '\IEEEPARstart');
Let('\pubid',              '\IEEEpubid');
Let('\pubidadjcol',        '\IEEEpubidadjcol');
Let('\specialpapernotice', '\IEEEspecialpapernotice');
# and environments
DefMacro(T_CS('\begin{keywords}'), '\@IEEEkeywords');
DefMacro(T_CS('\end{keywords}'),   '\@endIEEEkeywords');
DefMacro('\keywords', sub {
    my ($gullet) = @_;
    ($gullet->ifNext(T_BEGIN)
      ? (T_CS('\keywords@onearg'))
      : T_CS('\@IEEEkeywords')); },
  locked => 1);
DefMacro('\keywords@onearg{}', '\@IEEEkeywords #1 \@endIEEEkeywords');

# V1.8 no more support for legacy IED list commands
Let('\labelindent',      '\IEEElabelindent');
Let('\calcleftmargin',   '\IEEEcalcleftmargin');
Let('\setlabelwidth',    '\IEEEsetlabelwidth');
Let('\usemathlabelsep',  '\IEEEusemathlabelsep');
Let('\iedlabeljustifyc', '\IEEEiedlabeljustifyc');
Let('\iedlabeljustifyl', '\IEEEiedlabeljustifyl');
Let('\iedlabeljustifyr', '\IEEEiedlabeljustifyr');
# V1.8 no more support for QED and proof stuff
Let('\QED',       '\IEEEQED');
Let('\QEDclosed', '\IEEEQEDclosed');
Let('\QEDopen',   '\IEEEQEDopen');
DefMacro('\qed', '\ltx@qed');
DefConstructor('\ltx@qed',
  "?#isMath(<ltx:XMTok role='PUNCT'>\x{220E}</ltx:XMTok>)(\x{220E})",
  reversion => '\qed');
Let('\proof',    '\IEEEproof');
Let('\endproof', '\endIEEEproof');
# V1.8 no longer support biography or biographynophoto
Let('\biography',           '\IEEEbiography');
Let('\biographynophoto',    '\IEEEbiographynophoto');
Let('\endbiography',        '\endIEEEbiography');
Let('\endbiographynophoto', '\endIEEEbiographynophoto');

# The \bstctlcite command
#    which is used to invoke a BibTeX style control bibliography entry that can alter the formatting of .bst files that support it (such as IEEEtran.bst).
# see docs at http://www.michaelshell.org/tex/ieeetran/tools/
# TODO: Maybe once we can emulate ".bst" files natively this comes into play?
DefMacro('\bstctlcite[]{}', Tokens());

#======================================================================

1;
